package com.anyou.mall.wxrefund;

import com.alibaba.fastjson.JSONObject;
import com.anyou.common.core.domain.ApiResult;
import com.anyou.common.exception.GlobalException;
import com.anyou.common.utils.StringUtils;
import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;

@Service
@Slf4j
public class WxRefundService {

    @Autowired
    public WechatPay wechatPay;
    @Autowired
    public WechatPayH5 wechatPayH5;
    @Autowired
    private WxPayConfiguration wxPayConfiguration;


    /**
     * 微信退款
     * @param wxRefundParam
     * @return
     */
    public ApiResult wxRefund(WxRefundParam wxRefundParam)  {
        WxPayService wxPayService = wxPayConfiguration.wxService();
        WxPayRefundRequest wxPayRefundRequest = new WxPayRefundRequest();
        wxPayRefundRequest.setRefundFee(new BigDecimal(wxRefundParam.getRefundFee()).multiply(new BigDecimal(100)).intValue());
        wxPayRefundRequest.setTotalFee(new BigDecimal(wxRefundParam.getTotalFee()).multiply(new BigDecimal(100)).intValue());
        wxPayRefundRequest.setOutTradeNo(wxRefundParam.getOrderNo());
        wxPayRefundRequest.setOutRefundNo(wxRefundParam.getRefundNo());
        // 设置微信退款的回调地址
        wxPayRefundRequest.setNotifyUrl(wxPayConfiguration.getProperties().getRefundNotifyUrl());
        WxPayRefundResult refund = null;
        try {
            refund = wxPayService.refund(wxPayRefundRequest);
            log.info("微信退款返回信息:{}",refund);
            if("SUCCESS".equals(refund.getResultCode())){
                log.info("申请退款成功,微信官方正在处理退款");
                return ApiResult.success("申请退款成功,微信官方正在处理退款");
            }
            return ApiResult.error("退款失败");
        } catch (WxPayException e) {
            log.error("微信退款异常!错误码:"+e.getErrCode()+",错误信息:"+e.getCustomErrorMsg()+",返回码:"+e.getResultCode()+",返回信息:"+e.getReturnMsg(),e);
            return ApiResult.error("微信退款失败，请稍后重试");
        }

    }

    public static void main(String[] args) {
        String sign  = "appid=wx6fe3bc497d33e4b7&mch_id=1621853969&nonce_str=1651977472105&notify_url=http://1.13.4.122:8081/anyou-mini/wx/ctr/wxRefundNotify&op_user_id=1621853969&out_refund_no=s220507172613112717&out_trade_no=tc220507172153988684&refund_fee=1&total_fee=1&key=JZaj87vSQpmNWwe9H5HHdM7yEw7NNZAF";
        System.out.println(DigestUtils.md5Hex(sign).toUpperCase());;
    }

    /**
     * 订单支付(h5)
     * @param wechatPayParam
     * @param request
     * @return
     */
    public ApiResult orderPay(WechatPayParam wechatPayParam, HttpServletRequest request) {
        log.info("活动订单: {} 开始微信支付", wechatPayParam.getOrderNo());
        //支付金额(分)
        String money=wechatPayParam.getMoney().multiply(new BigDecimal(100)).intValue()+"";
        // 调用serviceH5支付
        Map<String, String> resmap = wechatPayH5("星钻充值", null, wechatPayParam.getOrderNo(), money, request);
        if(!resmap.get("return_code").equals("SUCCESS")){
            String return_msg = resmap.get("return_msg");
            return ApiResult.error("微信支付失败,微信返回的信息为:"+return_msg);
        }
        // 得到支付页面的url
        String url=resmap .get("mweb_url");
        if(StringUtils.isEmpty(url)){
            return ApiResult.error("微信支付失败, 获取到的支付url为空");
        }
//             //拼接支付成功后要返回的页面地址,如果不指定,会返回默认的发起支付的页面
//            url = url + "&redirect_url="+ URLEncoder.encode(wechatPayH5.redirect_url, "utf-8");
        return ApiResult.success(url);
    }

    /**
     * h5微信支付
     * @param remark
     * @param attach
     * @param out_trade_no
     * @param money
     * @param request
     * @return
     */
    public Map<String, String> wechatPayH5(String remark, String attach, String out_trade_no, String money, HttpServletRequest request) {
        String requestIp = CommonUtils.getIpAddr(request);
        //返回参数
        SortedMap<String,String> params = new TreeMap<>();
        params.put("appid", wechatPayH5.getAppId());
        params.put("mch_id", wechatPayH5.getMchId().toString());
        params.put("nonce_str", CommonUtils.generateUUID()); // 随机字符串, 请求参数需要
        params.put("body", remark); // 支付备注
        params.put("out_trade_no", out_trade_no); // 订单号
        params.put("total_fee", money); // 支付金额
        params.put("spbill_create_ip",requestIp); // 设置创建订单的ip地址,不太明白是什么ip.有人用当前服务器的ip,我这里直接使用用户请求的ip,没有发现有什么影响.
        params.put("notify_url",wechatPayH5.callback); // 支付回调,也就是支付成功后,我们业务员上需要做的操作
        params.put("trade_type", "MWEB"); // 交易类型,这里为H5
        String sign = WXPayUtil.createSign(params, wechatPayH5.getMchKey());
        params.put("sign",sign);
        String payXml;
        try {
            // 微信支付要求调用统一下单接口的必须是一个xml
            payXml = WXPayUtil.mapToXml(params);
            log.info("payXml: "+payXml);
            // 调用微信的统一下单接口
            String orderStr = HttpUtils.doPost("https://api.mch.weixin.qq.com/pay/unifiedorder",payXml,4000);
            if(StringUtils.isEmpty(orderStr)){
                log.error("微信支付失败.原因: 调用微信统一下单接口失败");
                return null;
            }
            log.info("orderStr: "+orderStr);
            // 调用成功, 返回的结果也是一个xml,例:<xml><return_code><![CDATA[FAIL]]></return_code>
            // 需要将返回的XML转化为一个map, 方便操作.
            Map<String, String> unifiedOrderMap =  WXPayUtil.xmlToMap(orderStr);
            return unifiedOrderMap;
        } catch (Exception e) {
//            e.printStackTrace();
            log.error("微信支付失败.原因: map参数转xml失败({})", e.getMessage());
            throw new GlobalException("微信支付失败.原因: map参数转xml失败,"+e.getMessage());
        }

    }

}
